import {
    OnChanges, OnInit, DoCheck, AfterContentInit,
    AfterContentChecked, AfterViewInit, AfterViewChecked,
    OnDestroy, SimpleChanges, Input, Output, EventEmitter
} from '@angular/core';
import { CommonModule } from "@angular/common";
import { FormsModule } from "@angular/forms";

import { LoggerService } from './logger';
import { IExtensibleObject, IExtensionCollection, IExtension } from "app/share/extension";


interface IStyleSetting {
    style: any;
    styleClass: string;
}

abstract class StyleSetting implements IStyleSetting {
    @Input() style: any;
    @Input() styleClass: string;
    mergedStyleSetting: IStyleSetting;

    abstract mergeStyleSettings(source: IStyleSetting, target: IStyleSetting): IStyleSetting;
}

function mergeStyleSettings(source: IStyleSetting, target: IStyleSetting): IStyleSetting {
    return source;
}

export class ComponentBase implements OnChanges, OnInit, DoCheck, AfterContentInit,
    AfterContentChecked, AfterViewInit, AfterViewChecked,
    OnDestroy {

    protected id: number;
    @Input() public displayName: string;
    @Output() public evt: EventEmitter<any>;

    constructor() {
        this.internalConsoleLog('constructor');
    }

    ngOnChanges(changes: SimpleChanges): void {
        let countOfChanges = 0;
        for (let propName in changes)
            countOfChanges++;

        this.internalConsoleLog(`ngOnChanges ${countOfChanges}`);
    }

    ngOnInit(): void {
        this.internalConsoleLog('ngOnInit');
    }

    ngDoCheck(): void {
        this.internalConsoleLog('ngDoCheck');
    }

    ngAfterContentInit(): void {
        this.internalConsoleLog('ngAfterContentInit');
    }

    ngAfterContentChecked(): void {
        this.internalConsoleLog('ngAfterContentChecked');
    }

    ngAfterViewInit(): void {
        this.internalConsoleLog('ngAfterViewInit');
    }

    ngAfterViewChecked(): void {
        this.internalConsoleLog('ngAfterViewChecked');
    }

    ngOnDestroy(): void {
        this.internalConsoleLog('ngOnDestroy');
    }

    protected internalConsoleLog(lifeCycle: string) {
        console.log(`【${this.constructor.name}】- ${lifeCycle} at ${new Date()}`);
    }
}


export abstract class ExtendableComponentBase
    extends ComponentBase
    implements OnInit, OnDestroy, IExtensibleObject<ExtendableComponentBase> {
    extensions: IExtension<ExtendableComponentBase>[];
    constructor(extensions: IExtension<ExtendableComponentBase>[]) {
        super();
        this.extensions = extensions ? extensions : [];
    }

    ngOnInit() {
        this.extensions.map(e => e.attach(this));
        super.ngOnInit();
    }

    ngOnDestroy() {
        this.extensions.map(e => e.detach(this));
        super.ngOnDestroy();
    }
}

export const NG_ROOT_MODULES = [
    CommonModule,
    FormsModule
];
